package com.csw.rediscachedemo.aspect;


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import util.res.Result;
import util.res.StatusCode;

import java.lang.reflect.Method;


@Aspect
@Component
@Slf4j
public class CacheAspect {


    //要扫描的方法必须是public
    @Around("@annotation(com.csw.rediscachedemo.aspect.RedisCache)")
    public Object around(ProceedingJoinPoint point){
        try {
            Signature signature = point.getSignature();
            String className = point.getTarget().getClass().getSimpleName();
            String methodName = signature.getName();

            if(methodName.equals("getArchives")){

            }

            Class[] paramerterTypes = new Class[point.getArgs().length];
            Object[] args = point.getArgs();

            String params = "";
            for (int i = 0; i < args.length; i++) {
                if(args[i] != null){
                    params += JSON.toJSONString(args[i]);
                    paramerterTypes[i] = args[i].getClass();
                }else {
                    paramerterTypes[i] = null;
                }
            }
            if(StringUtils.isNotEmpty(params)){
                params =  DigestUtils.md5Hex(params.replaceAll("\"", ""));
            }
            Method method = point.getSignature().getDeclaringType().getMethod(methodName,paramerterTypes);
            RedisCache annotation = method.getAnnotation(RedisCache.class);
            long expire = annotation.expire();
            String name = annotation.name();
            String redisKey = name + ":" + className + ":" + methodName + ":" + params;
            log.info("key====>"+redisKey);
            Object aa = RedisUtil.selectRedis(redisKey, expire, point);
            log.info("存入缓存--"+className+"类==》方法："+methodName);
            return aa;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            log.error("缓存错误--->");
        }
        return new Result(false, StatusCode.ERROR,"","");
    }
}
